package com.gitee.ice1938.module.admin.framwork;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.WebUtils;

import com.gitee.ice1938.module.admin.core.operator.fun.OperatorService;
import com.gitee.ice1938.module.admin.framwork.core.MenuItem;
import com.gitee.ice1938.module.admin.framwork.core.Operation;

public class DefaultMenuFilter implements AdminMenuFilter {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(DefaultMenuFilter.class);

	private static final String ACTIVE_MENU = "active_menu";
	private static final String MENU_TWO = "menu_two";
	private static final String MENU_GROUP = "menu_one";
	// Order defaults to after OrderedRequestContextFilter filter
	private int order = REQUEST_WRAPPER_FILTER_MAX_ORDER + 10;

	@Autowired
	private OperatorService operatorService;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
	        ServletException {
		HttpServletRequest request_ = (HttpServletRequest) request;

		logger.info("{},HttpSession {}", request_.getRequestURL(), WebUtils.getSessionId(request_));
		boolean isload = false;
		List<MenuItem> oneLevel = (List<MenuItem>) WebUtils.getSessionAttribute(request_,MENU_GROUP);
		if (oneLevel != null && !oneLevel.isEmpty()) {
			isload = true;
		}
		Set<MenuItem> twoLevel = (Set<MenuItem>) WebUtils.getSessionAttribute(request_,MENU_TWO);
		if (twoLevel != null && !twoLevel.isEmpty()) {
			isload = true;
		}
		if (!isload && isLongin(request_)) {
			// 包括(一级)目录和二级页面
			Set<MenuItem> contextMenus = operatorService.appMenus();
			Set<MenuItem> requestMenus = builderRealMenus(request_, contextMenus);
			List<MenuItem> grpl = builderMenuGroup(request_, requestMenus, contextMenus);
			WebUtils.setSessionAttribute(request_, MENU_TWO, requestMenus);
			WebUtils.setSessionAttribute(request_, MENU_GROUP, grpl);
		}
		createActive(request_);
		chain.doFilter(request, response);
	}

	protected Set<MenuItem> builderRealMenus(HttpServletRequest request, Set<MenuItem> contextMenus) {
		Set<MenuItem> menus = new HashSet<>();
		// 筛选二级菜单
		for (MenuItem menuItem : contextMenus) {
			if (!isCapability(request, menuItem.getCapability())) {
				continue;
			}
			// // 说明是一级菜单，二级菜单是的''
			if (menuItem.getType() == Operation.Type.dir.value()) {
				continue;
			}
			menus.add(menuItem);
		}
		return menus;
	}

	protected boolean isCapability(HttpServletRequest request, String capability) {
		return true;
	}

	protected boolean isLongin(HttpServletRequest request) {
		return request.getSession(true) != null;
	}

	protected List<MenuItem> builderMenuGroup(HttpServletRequest request, Set<MenuItem> requestMenus,
	        Set<MenuItem> contextMenus) {
		Map<String, MenuItem> menuGroupMap = getGroups(contextMenus);
		// 构建二级子菜单
		MenuItem group = null;
		List<MenuItem> grpl = new ArrayList<>();
		MenuItem[] arr = requestMenus.toArray(new MenuItem[] {});
		for (int i = 0, size = arr.length; i < size; i++) {
			MenuItem menuItem = arr[i];
			String groupid = menuItem.getParentId();
			group = menuGroupMap.get(groupid);
			if (group != null) {
				group.addMenu(menuItem);
				requestMenus.remove(menuItem);
				grpl.add(group);
			}
		}
		Collections.sort(grpl);
		return grpl;
	}

	private Map<String, MenuItem> getGroups(Set<MenuItem> contextMenus) {
		// 构建menugroup(一级菜单)
		Map<String, MenuItem> menuGroupMap = new LinkedHashMap<String, MenuItem>();
		for (MenuItem menuItem : contextMenus) {
			int type = menuItem.getType();
			if (type == Operation.Type.dir.value()) {
				MenuItem i = new MenuItem();
				i.setId(menuItem.getId());
				i.setParentId(null);
				i.setTitle(menuItem.getText());
				i.setTarget(menuItem.getTarget());
				i.setCapability(menuItem.getCapability());
				i.setPosition(menuItem.getPosition());
				i.setIconClass(menuItem.getIconClass());
				i.setType_(type);
				menuGroupMap.putIfAbsent(menuItem.getId(), i);
			}
		}
		return menuGroupMap;
	}

	private void createActive(HttpServletRequest request) {
		Set<MenuItem> menus = (Set<MenuItem>) WebUtils.getSessionAttribute(request, MENU_TWO);
		String requestURI = request.getRequestURI().replaceFirst(request.getContextPath(), "");
		if (menus != null) {
			for (MenuItem menuItem : menus) {
				if (menuItem.getUri() != null && menuItem.getUri().indexOf(requestURI) > -1) {
					WebUtils.setSessionAttribute(request, ACTIVE_MENU, menuItem);
					break;
				}
			}
		}
	}

	@Override
	public int getOrder() {
		return this.order;
	}

	@Override
	public String toString() {
		return "DefaultMenuFilter [order=" + order + "]";
	}

}
